﻿#define IncludeLibrary
using System;

namespace Meta
{
	/// <summary>
	/// Summary description for StandardLibrary.
	/// </summary>
	public class StandardLibrary
	{
		public static void Initialize() {
#if IncludeLibrary
			EvalStack.CurrentThreadEvalStack.Clear();
			EvalStack.CurrentThreadEvalStack.Push("initialize", new object[0]);
			TopLevel.LoadStream(new Reader(new System.IO.StringReader(@"[define cond
[with beginify = [body →
[if [= [length body] 1]
[first body]
[cons 'begin body]]]
[macro [clauses ... →
[with loop : clauses = clauses
[with clause = [first clauses]
[if [= [first clause] 'else]
[if [> [length clauses]
1]
[syntax-error “Extra clauses after else”
[rest clauses]]
[beginify [rest clause]]]
[if [= [length clauses]
1]
[list 'if
[first clause]
[beginify [rest clause]]]
[list 'if
[first clause]
[beginify [rest clause]]
[loop [rest clauses]]]]]]]]]]]



[define quasiquote
[with* parse-quasiquoted = [expression →
[if [list? expression]
[if [≥ [length expression]
1]
[with operator = [first expression]
[cond [[= operator 'unquote]
[if [= [length expression] 2]
[list 'list
[second expression]]
[syntax-error “Malformed unquote expression”
expression]]]
[[= operator 'unquote-splicing]
[if [= [length expression] 2]
[second expression]
[syntax-error “Malformed unquote-splicing expression”
expression]]]
[else
[list 'list
[optimize-quasiquote [map parse-quasiquoted
expression]]]]]]
'[quote []]]
[list 'list
[list 'quote expression]]]]
optimize-quasiquote = [with list-call? = [e → [and [list? e]
[> [length e] 1]
[= [first e] 'list]]]
quoted? = [e → [and [list? e]
[> [length e] 1]
[= [first e] 'quote]]]
[append-args →
[if [every list-call? append-args]
«We don't need to do an append, since we're appending fixed-size lists»
[with list-args = [apply append [map rest append-args]]
[if [every quoted? list-args]
«In the end, it's just a quoted list»
[list 'quote
[map second list-args]]
[cons 'list list-args]]]
[cons 'append append-args]]]]
[macro [e →
[with listified-answer = [parse-quasiquoted e]
[if [and [list? listified-answer]
[= [length listified-answer] 2]
[= [first listified-answer] 'list]]
[second listified-answer]
[syntax-error “Malformed quasiquote expression” e]]]]]]]

[define define-macro
[macro [name-and-args body ... →
[with name = [first name-and-args]
args = [rest name-and-args]
`[define ,name
[macro [,@args → ,@body]]]]]]]
[define-macro.indentStyle <- 'body]

[define case
[with compile-clause = [c v →
[if [= [first c] 'else]
c
`[[contains? ,v ',[first c]]
,@[rest c]]]]
[macro [exp clauses ... →
[with v = [local-variable 'case]
[if [symbol? exp]
`[cond ,@[map [c → [compile-clause c exp]]
clauses]]
`[with ,v = ,exp
[cond ,@[map [c → [compile-clause c v]]
clauses]]]]]]]]]
[define-macro [define-method name-and-args body ...]
[with* generic = [first name-and-args]
args = [rest name-and-args]
arg-types = [map [get-type : arg →
[if [list? arg]
[first arg]
'Object]]
args]
arg-names = [map [get-name : arg →
[if [list? arg] [second arg] arg]]
args]
`[[member ,generic
“SetMethod”]
[list ,@arg-types]
[,@arg-names → ,@body]]]]
[define-method.indentStyle ← 'body]


"), 0));
#endif
		}
	}
}
